const canvas = document.getElementById('canvas') as HTMLCanvasElement
const ctx = canvas.getContext('2d')

let score = 0
let beginTime = new Date()
let second = 0

const brickRowCount = 5 // 5行
const brickColumnCount = 9 // 9列

// Create ball props
const ball = {
  x: canvas.width / 2,
  y: canvas.height / 2,
  size: 10,
  speed: 4,
  dx: 4,
  dy: -4,
}

// Create paddle props
const paddle = {
  x: canvas.width / 2 - 50,
  y: canvas.height - 20,
  w: 100,
  h: 10,
  speed: 8,
  dx: 0,
}

// Create brick props
const brickInfo = {
  w: 70,
  h: 20,
  padding: 10,
  offsetX: 45,
  offsetY: 60,
  visible: true,
}

// Create bricks
const bricks = []
for (let i = 0; i < brickRowCount; i++) {
  bricks[i] = []
  for (let j = 0; j < brickColumnCount; j++) {
    const x = j * (brickInfo.w + brickInfo.padding) + brickInfo.offsetX
    const y = i * (brickInfo.h + brickInfo.padding) + brickInfo.offsetY
    bricks[i][j] = { x, y, ...brickInfo }
  }
}

// Draw ball on canvas
function drawBall() {
  ctx.beginPath()
  ctx.arc(ball.x, ball.y, ball.size, 0, 2 * Math.PI)
  ctx.fillStyle = '#786f69'
  ctx.fill()
  ctx.closePath()
}

// Draw paddle on canvas
function drawPaddle() {
  ctx.beginPath()
  ctx.rect(paddle.x, paddle.y, paddle.w, paddle.h)
  ctx.fillStyle = '#786f69'
  ctx.fill()
  ctx.closePath()
}

// Draw bricks on canvas
function drawBricks() {
  bricks.forEach((row) => {
    row.forEach((brick) => {
      ctx.beginPath()
      ctx.rect(brick.x, brick.y, brick.w, brick.h)
      ctx.fillStyle = brick.visible ? '#786f69' : 'transparent'
      ctx.fill()
      ctx.closePath()
    })
  })
}

// Draw score on canvas
function drawScore() {
  ctx.font = '20px Arial'
  ctx.fillText(`Time: ${second}  Score: ${score}`, canvas.width - 175, 30)
}

// Move paddle on canvas
function movePaddle() {
  paddle.x += paddle.dx

  if (paddle.x + paddle.w > canvas.width) {
    paddle.x = canvas.width - paddle.w
  }
  if (paddle.x < 0) {
    paddle.x = 0
  }
}

function moveBall() {
  ball.x += ball.dx
  ball.y += ball.dy

  // Wall collision (right/left)
  if (ball.x + ball.size > canvas.width || ball.x - ball.size < 0) {
    ball.dx *= -1
  }
  // Wall collision (top/bottom)
  if (ball.y + ball.size > canvas.height || ball.y - ball.size < 0) {
    ball.dy *= -1
  }
  // Paddle collision
  if (ball.y + ball.size > paddle.y && ball.x > paddle.x && ball.x < paddle.x + paddle.w) {
    ball.dy = -ball.speed
  }
  // Brick collision
  bricks.forEach((row) => {
    row.forEach((brick) => {
      if (
        brick.visible &&
        ball.y + ball.size > brick.y && // top side
        ball.x - ball.size < brick.x + brick.w && // right side
        ball.y - ball.size < brick.y + brick.h && // bottom side
        ball.x + ball.size > brick.x // left side
      ) {
        ball.dy *= -1
        brick.visible = false
        score++
      }
    })
  })
  // Hit bottom wall
  if (ball.y + ball.size > canvas.height) {
    bricks.forEach((column) => {
      column.forEach((brick) => (brick.visible = true))
    })
    score = 0
    beginTime = new Date()
    second = 0
  }
}

// Draw everything
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height)

  drawBall()
  drawPaddle()
  drawScore()
  drawBricks()
}

function update() {
  movePaddle()
  moveBall()

  draw()

  requestAnimationFrame(update)
}

// Keydown event
function keyDown(e: KeyboardEvent) {
  if (e.key === 'Right' || e.key === 'ArrowRight') {
    paddle.dx = paddle.speed
  } else if (e.key === 'Left' || e.key === 'ArrowLeft') {
    paddle.dx = -paddle.speed
  }
}

// Keyup event
function keyUp(e: KeyboardEvent) {
  if (e.key === 'Left' || e.key === 'ArrowLeft' || e.key === 'Right' || e.key === 'ArrowRight') {
    paddle.dx = 0
  }
}

// Key event
document.addEventListener('keydown', keyDown)
document.addEventListener('keyup', keyUp)

update()


setInterval(updateTime, 1000)

function updateTime() {
  const currentTime = new Date()
  const diff = Number(currentTime) - Number(beginTime)
  second = Math.floor(diff / 1000)
}
